home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / misc_pto / basic-c / basic.c next >
C/C++ Source or Header  |  1988-12-21  |  16KB  |  874 lines

  1. /*********************************************************
  2.  *     A tiny BASIC interpreter adapted from:             *
  3.  *                                                       *
  4.  *        C: Power User's Guide                    *
  5.  *            by                               *
  6.  *           Herbert Schildt                        *
  7.  *                                                       *
  8.  *      Published by Osborne/McGraw-Hill,              *
  9.  *    Copyright 1987, Osborne/McGraw-Hill.             *
  10.  *********************************************************/
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include <ctype.h>
  15. #include <fcntl.h>
  16. #include <string.h>
  17. #include <time.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20.  
  21. #ifdef MSDOS
  22. #include <dos.h>
  23. #include <stdlib.h>
  24. #else
  25. #include "term.h"
  26. #endif
  27.  
  28.  
  29. #include "defines.h"
  30.  
  31. jmp_buf e_buf;            /* hold environment for longjmp() */
  32.  
  33. struct commands {        /* keyword lookup table */
  34.     char    command[20];    /* command name */
  35.     char    tokenid;    /* command token value */
  36. } table[] = {            /* entries here must be lowercase */
  37.     "print",     PRINT,
  38.     "input",     INPUT,
  39.     "if",         IF,
  40.     "then",     THEN,
  41.     "goto",     GOTO,
  42.     "for",         FOR,
  43.     "next",     NEXT,
  44.     "to",         TO,
  45.     "gosub",     GOSUB,
  46.     "return",     RETURN,
  47.     "shell",     SHELL,
  48.     "move",     MOVE,
  49.     "cls",         CLS,
  50.     "rem",         REMARK,
  51.     "beep",     BEEP,
  52.     "sleep",     SLEEP,
  53.     "time",        TIME,
  54.     "date",        DATE,
  55.     "end",         END,
  56.     "",         END    /* mark end of table */
  57. };
  58.  
  59.  
  60. struct for_stack {
  61.     int    var;        /* counter variable */
  62.     int    target;        /* target value */
  63.     char    *loc;
  64. } fstack[FOR_NEST];        /* stack for FOR/NEXT loop */
  65.  
  66. struct for_stack fpop();
  67.  
  68. char    token[BUFSIZ];
  69. char    *p_buf;
  70. char    *gpop();
  71. char    *load();
  72. char    *prog;            /* holds expression to be analyzed */
  73. char    *gstack[SUB_NEST];    /* stack for gosub */
  74.  
  75. int    tokentype;
  76. int    tokenstat;
  77. int    ftos;            /* index to top of FOR stack */
  78. int    gtos;            /* index to top of gosub stack */
  79.  
  80. int    variables[26] = {    /* 26 user variables,  A-Z */
  81.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  82.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  83. };
  84.  
  85.  
  86. void b_print(), geteol(), b_goto(), b_sleep();
  87. void b_if (), b_for(), b_next(), fpush(), b_input();
  88. void getexp(), level2(), level3(), level4(), level5();
  89. void level6(), primitive(), arith(), unary(), b_shell();
  90. void b_error(), putback(), b_gosub(), b_return(), b_remark();
  91. void gpush(), b_move(), b_cls(), b_beep(), b_time(), b_date();
  92.  
  93. main(argc, argv)
  94. int    argc;
  95. char    *argv[];
  96. {
  97.  
  98.     if (argc != 2) {
  99.         fprintf (stderr, "usage: basic <progname>[.bas]\n");
  100.         exit(1);
  101.     }
  102.  
  103.     setbuf(stdin, NULL);
  104.     setbuf(stdout, NULL);
  105.     setbuf(stderr, NULL);
  106.  
  107. #ifndef MSDOS
  108.     gettermtype();
  109. #endif
  110.     /* load the program to execute */
  111.     if ((p_buf = load(argv[1])) == NULL) {
  112.         fprintf(stderr, "\nBASIC: can not load %s", argv[1]);
  113.         exit(1);
  114.     }
  115.  
  116.     /* initialize the long jump buffer */
  117.     if (setjmp(e_buf))
  118.         exit(1);
  119.     prog = p_buf;
  120.     initlabels(token);    /* find the labels in the program */
  121.     ftos = 0;        /* initialize the FOR stack index */
  122.     gtos = 0;        /* initialize the gosub stack index */
  123.  
  124.     do {
  125.         /* get first token to get ball rolling */
  126.         tokentype = gettoken(token);
  127.  
  128.         /* check for assignment statement */
  129.         if (tokentype == VARIABLE) {
  130.             putback(token);        /* put token back */
  131.             assignment(token);    /* must be assignment */
  132.         } else {            /* token must be a command */
  133.             switch (tokenstat) {
  134.             case PRINT:
  135.                 b_print(token);
  136.                 break;
  137.             case GOTO:
  138.                 b_goto(token);
  139.                 break;
  140.             case IF:
  141.                 b_if(token);
  142.                 break;
  143.             case FOR:
  144.                 b_for(token);
  145.                 break;
  146.             case NEXT:
  147.                 b_next();
  148.                 break;
  149.             case INPUT:
  150.                 b_input(token);
  151.                 break;
  152.             case GOSUB:
  153.                 b_gosub(token);
  154.                 break;
  155.             case RETURN:
  156.                 b_return();
  157.                 break;
  158.             case SHELL:
  159.                 b_shell(token);
  160.                 break;
  161.             case CLS:
  162.                 b_cls();
  163.                 break;
  164.             case MOVE:
  165.                 b_move(token);
  166.                 break;
  167.             case REMARK:
  168.                 b_remark();
  169.                 break;
  170.             case BEEP:
  171.                 b_beep(token);
  172.                 break;
  173.             case SLEEP:
  174.                 b_sleep(token);
  175.                 break;
  176.             case TIME:
  177.                 b_time();
  178.                 break;
  179.             case DATE:
  180.                 b_date();
  181.                 break;
  182.             case END:
  183.                 b_cls();
  184.                 tokenstat = FINISHED;
  185.                 break;
  186.             }
  187.         }    /* end of 'else' */
  188.     } while (tokenstat != FINISHED);
  189.     exit(0);
  190. }
  191.  
  192.  
  193. /*
  194.  * load - allocate sufficient memory if possible,
  195.  * then load the user BASIC program into memory.
  196.  * returns pointer to program in allocated memory.
  197.  */
  198. char    *
  199. load(fname)
  200. char    *fname;
  201. {
  202.     int    fp, r;
  203.     char    ifile[15], *b;
  204.     struct stat st;
  205.  
  206.     strcpy(ifile, fname);            /* save partial name */
  207.     if (!strchr(ifile, '.'))        /* check for extension */
  208.         strcat(ifile, ".bas");        /* add ".bas" to file name */
  209.  
  210.     /* attempt to open file */
  211.     if ((fp = open (ifile, O_RDONLY | O_TEXT)) == EOF) {
  212.         fprintf (stderr, "\nBASIC: program open error: %s\n", ifile);
  213.         return (NULL);
  214.     }
  215.  
  216.     /* determine amount of memory required */
  217.     if (fstat (fp, &st)) {
  218.         fprintf (stderr, "\nBASIC: program status error\n");
  219.         close (fp);
  220.         return (NULL);
  221.     } else
  222.         fprintf(stderr, "\nBASIC: program size: %d\n", st.st_size);
  223.  
  224.     /* allocate memory for the program */
  225.     if ((b = (char *)calloc(1, st.st_size + 1)) == NULL) {
  226.         fprintf (stderr, "\nBASIC: memory allocation failure\n");
  227.         close (fp);
  228.         return (NULL);
  229.     }
  230.  
  231.     /* read file into zeroed memory */
  232.     r = read (fp, b, (unsigned )st.st_size);
  233.  
  234.     /* check for EOF instead of amount read */
  235.     /* in consideration of the MSDOS O_TEXT */
  236.     /* mode, which could be less due to CRLF */
  237.     /* translation to LF only */
  238.     if (r == EOF) {
  239.         fprintf(stderr, "\nBASIC: program file load error\n");
  240.         close (fp);
  241.         return (NULL);
  242.     } else
  243.         fprintf(stderr, "BASIC: loaded size: %d\n", r);
  244.  
  245.     close (fp);        /* done with file, so close it */
  246.     return (b);        /* return pointer to memory */
  247. }
  248.  
  249.  
  250. /*
  251.  * gettoken - get a token and place it in gtoken.
  252.  */
  253. int
  254. gettoken(gtoken)
  255. char    *gtoken;
  256. {
  257.     char    *temp;
  258.  
  259.     tokentype     = 0;
  260.     tokenstat     = 0;
  261.     temp         = gtoken;
  262.  
  263.     if (*prog == NULL) {        /* end of file */
  264.         gtoken[0] = NULL;
  265.         tokenstat = FINISHED;
  266.         return(DELIMITER);
  267.     }
  268.  
  269.     while (iswhite(*prog))
  270.         ++prog;            /* skip over white space */
  271.  
  272.     if (*prog == '\n') {        /* LF */
  273.         ++prog;
  274.         if (*prog)
  275.             tokenstat = EOL;
  276.         else
  277.             tokenstat = FINISHED;
  278.         gtoken[0] = '\n';
  279.         gtoken[1] = NULL;
  280.         return (DELIMITER);
  281.     }
  282.  
  283.     if (strchr("+-*^/%=;(),><", *prog)) {    /* delimiter */
  284.         *temp = *prog;        /* white space already skipped */
  285.         prog++;            /* advance to next position */
  286.         temp++;
  287.         *temp = NULL;
  288.         return (DELIMITER);
  289.     }
  290.  
  291.     if (*prog == '"') {            /* quoted string */
  292.         prog++;                /* step over quote */
  293.  
  294.         while (*prog && *prog != '"' && *prog != '\n')
  295.             *temp++ = *prog++;    /* copy string to temp */
  296.  
  297.         if (*prog == '\n' || *prog == NULL)
  298.             b_error(16);        /* unbalanced quotes */
  299.  
  300.         prog++;                /* step over end quote */
  301.         *temp = NULL;            /* terminate temp */
  302.         return(QUOTE);
  303.     }
  304.  
  305.     if (isdigit(*prog)) {            /* number */
  306.         while (!isdelim(*prog))
  307.             *temp++ = *prog++;
  308.         *temp = NULL;
  309.         return(NUMBER);
  310.     }
  311.  
  312.     if (isalpha(*prog)) {            /* var or command */
  313.         while (!isdelim(*prog))
  314.             *temp++ = *prog++;
  315.         tokentype = STRING;
  316.     }
  317.  
  318.     *temp = NULL;
  319.  
  320.     /* see if a string is a command or a variable */
  321.     if (tokentype == STRING) {
  322.         tokenstat = look_up(gtoken);    /* convert to internal rep */
  323.         if (!tokenstat)
  324.             tokentype = VARIABLE;
  325.         else
  326.             tokentype = COMMAND;    /* is a command */
  327.     }
  328.     return (tokentype);
  329. }
  330.  
  331.  
  332.  
  333. /*
  334.  * assignment - assign a value to a variable 
  335.  */
  336. assignment(atoken)
  337. char    *atoken;
  338. {
  339.     int    var, value;
  340.  
  341.     /* get the variable name */
  342.     tokentype = gettoken(atoken);
  343.     if (!isalpha (*atoken)) {
  344.         b_error(4);
  345.         return;
  346.     }
  347.  
  348.     var = toupper(*atoken) - 'A';    /* calculate the variable's offset */
  349.  
  350.     /* get the equals sign */
  351.     tokentype = gettoken(atoken);
  352.     if (*atoken != '=') {
  353.         b_error(3);
  354.         return;
  355.     }
  356.  
  357.     /* get the value to assign to variable */
  358.     getexp(atoken, &value);
  359.  
  360.     /* assign the value */
  361.     variables[var] = value;
  362.     return;
  363. }
  364.  
  365.  
  366. /*
  367.  * geteol - find the start of the next line
  368.  */
  369. void
  370. geteol()
  371. {
  372.     while (*prog != '\n'  && *prog != NULL)
  373.         ++prog;
  374.     if (*prog)
  375.         prog++;
  376.     return;
  377. }
  378.  
  379.  
  380.  
  381. /*
  382.  * b_if - execute an IF statement
  383.  */
  384. void
  385. b_if(itoken)
  386. char    *itoken;
  387. {
  388.     int    x , y, cond;
  389.     char    op;
  390.  
  391.     getexp(itoken, &x);            /* get left expression */
  392.  
  393.     tokentype = gettoken(itoken);        /* get the operator */
  394.     if (!strchr("=<>", *itoken)) {
  395.         b_error(0);            /* not a legal operator */
  396.         return;
  397.     }
  398.     op = *itoken;
  399.  
  400.     getexp(itoken, &y);            /* get right expression */
  401.  
  402.     cond = 0;                /* determine the outcome */
  403.     switch (op) {
  404.     case '<':
  405.         if (x < y)
  406.             cond = 1;
  407.         break;
  408.     case '>':
  409.         if (x > y)
  410.             cond = 1;
  411.         break;
  412.     case '=':
  413.         if (x == y)
  414.             cond = 1;
  415.         break;
  416.     }
  417.     if (cond) {            /* true, so process target of IF */
  418.         tokentype = gettoken(itoken);
  419.         if (tokenstat != THEN) {
  420.             b_error(8);
  421.             return;
  422.         }
  423.     } else    /* execution starts on next line */
  424.         geteol();        /* find start of next line */
  425.     return;
  426. }
  427.  
  428.  
  429. /*
  430.  * b_for - execute a FOR loop
  431.  */
  432. void
  433. b_for(ftoken)
  434. char    *ftoken;
  435. {
  436.     struct for_stack i;
  437.     int    value;
  438.  
  439.     tokentype = gettoken(ftoken);        /* read the control variable */
  440.     if (!isalpha(*ftoken)) {
  441.         b_error(4);
  442.         return;
  443.     }
  444.  
  445.     i.var = toupper(*ftoken) - 'A';        /* save its index */
  446.  
  447.     tokentype = gettoken(ftoken);        /* read the equals sign */
  448.     if (*ftoken != '=') {
  449.         b_error(3);
  450.         return;
  451.     }
  452.  
  453.     getexp(ftoken, &value);            /* get initial value */
  454.  
  455.     variables[i.var] = value;
  456.  
  457.     tokentype = gettoken(ftoken);
  458.     if (tokenstat != TO)
  459.         b_error(9);        /* read and discard the TO */
  460.  
  461.     getexp(ftoken, &i.target);    /* get target value */
  462.  
  463.     /* if loop can execute at least once, push info on stack */
  464.     if (value >= variables[i.var]) {
  465.         i.loc = prog;
  466.         fpush(i);
  467.     } else    /* otherwise, skip loop code */
  468.         while (tokenstat != NEXT)
  469.             tokentype = gettoken(ftoken);
  470.     return;
  471. }
  472.  
  473.  
  474. /*
  475.  * next - execute a NEXT statement
  476.  */
  477. void
  478. b_next()
  479. {
  480.     struct for_stack i;
  481.  
  482.     i = fpop();            /* read the loop info */
  483.  
  484.     variables[i.var]++;        /* increment control variable */
  485.     if (variables[i.var] > i.target)
  486.         return;            /* all done */
  487.     fpush(i);            /* otherwise, restore the info */
  488.     prog = i.loc;            /* loop */
  489.     return;
  490. }
  491.  
  492.  
  493. /*
  494.  * fpush - push function for the FOR stack
  495.  */
  496. void
  497. fpush(i)
  498. struct for_stack i;
  499. {
  500.     if (ftos > FOR_NEST)
  501.         b_error(10);
  502.  
  503.     fstack[ftos] = i;
  504.     ftos++;
  505.     return;
  506. }
  507.  
  508.  
  509. /*
  510.  * fpop - pop function from the FOR stack
  511.  */
  512. struct for_stack fpop()
  513. {
  514.     ftos--;
  515.     if (ftos < 0)
  516.         b_error(11);
  517.     return(fstack[ftos]);
  518. }
  519.  
  520.  
  521.  
  522. /*
  523.  * gpush - gosub stack push function
  524.  */
  525. void
  526. gpush(s)
  527. char    *s;
  528. {
  529.     gtos++;
  530.  
  531.     if (gtos == SUB_NEST) {
  532.         b_error(12);
  533.         return;
  534.     }
  535.  
  536.     gstack[gtos] = s;
  537.     return;
  538. }
  539.  
  540.  
  541. /*
  542.  * gpop - gosub stack pop function
  543.  */
  544. char    *
  545. gpop()
  546. {
  547.     if (gtos == 0) {
  548.         b_error(13);
  549.         return 0;
  550.     }
  551.     return(gstack[gtos--]);
  552. }
  553.  
  554.  
  555. /*
  556.  * getexp - entry point into parser
  557.  */
  558. void
  559. getexp(xtoken, result)
  560. char    *xtoken;
  561. int    *result;
  562. {
  563.     tokentype = gettoken(xtoken);
  564.     if (!*xtoken) {
  565.         b_error(2);
  566.         return;
  567.     }
  568.     level2(xtoken, result);
  569.     putback(xtoken);         /* return last token to input */
  570.     return;
  571. }
  572.  
  573.  
  574. /*
  575.  * level2 - Add or subtract two terms
  576.  */
  577. void
  578. level2(xtoken, result)
  579. char    *xtoken;
  580. int    *result;
  581. {
  582.     register char    op;
  583.     int    hold;
  584.  
  585.     level3(xtoken, result);
  586.     while ((op = *xtoken) == '+' || op == '-') {
  587.         tokentype = gettoken(xtoken);
  588.         level3(xtoken, &hold);
  589.         arith(op, result, &hold);
  590.     }
  591.     return;
  592. }
  593.  
  594.  
  595. /*
  596.  * level3 - multiply or divide two factors. 
  597.  */
  598. void
  599. level3(xtoken, result)
  600. char    *xtoken;
  601. int    *result;
  602. {
  603.     register char    op;
  604.     int    hold;
  605.  
  606.     level4(xtoken, result);
  607.     while ((op = *xtoken) == '*' || op == '/' || op == '%') {
  608.         tokentype = gettoken(xtoken);
  609.         level4(xtoken, &hold);
  610.         arith(op, result, &hold);
  611.     }
  612.     return;
  613. }
  614.  
  615.  
  616. /*
  617.  * level4 - process integer exponent.
  618.  */
  619. void
  620. level4(xtoken, result)
  621. char    *xtoken;
  622. int    *result;
  623. {
  624.     int    hold;
  625.  
  626.     level5(xtoken, result);
  627.     if (*xtoken ==  '^') {
  628.         tokentype = gettoken(xtoken);
  629.         level4(xtoken, &hold);
  630.         arith('^', result, &hold);
  631.     }
  632.     return;
  633. }
  634.  
  635.  
  636. /*
  637.  * level5 - process a unary + or -.
  638.  */
  639. void
  640. level5(xtoken, result)
  641. char    *xtoken;
  642. int    *result;
  643. {
  644.     register char    op;
  645.  
  646.     op = NULL;
  647.     if ((tokentype == DELIMITER) && *xtoken == '+' || *xtoken == '-') {
  648.         op = *xtoken;
  649.         tokentype = gettoken(xtoken);
  650.     }
  651.     level6(xtoken, result);
  652.     if (op)
  653.         unary(op, result);
  654.     return;
  655. }
  656.  
  657.  
  658. /*
  659.  * level6 - process parenthesized expression.
  660.  */
  661. void
  662. level6(xtoken, result)
  663. char    *xtoken;
  664. int    *result;
  665. {
  666.     if ((*xtoken == '(') && (tokentype == DELIMITER)) {
  667.         tokentype = gettoken(xtoken);
  668.         level2(xtoken, result);
  669.         if (*xtoken != ')')
  670.             b_error(1);
  671.         tokentype = gettoken(xtoken);
  672.     } else
  673.         primitive(xtoken, result);
  674.     return;
  675. }
  676.  
  677.  
  678. /*
  679.  * primitive - find value of number or variable.
  680.  */
  681. void
  682. primitive(xtoken, result)
  683. char    *xtoken;
  684. int    *result;
  685. {
  686.  
  687.     switch (tokentype) {
  688.     case VARIABLE:
  689.         *result = getval(xtoken);
  690.         tokentype = gettoken(xtoken);
  691.         return;
  692.     case NUMBER:
  693.         *result = atoi(xtoken);
  694.         tokentype = gettoken(xtoken);
  695.         return;
  696.     default:
  697.         b_error(0);
  698.     }
  699.     return;
  700. }
  701.  
  702.  
  703. /*
  704.  * arith - perform the specified arithmetic.
  705.  */
  706. void
  707. arith(o, r, h)
  708. char    o;
  709. int    *r, *h;
  710. {
  711.     register int    t, ex;
  712.  
  713.     switch (o) {
  714.     case '-':
  715.         *r = *r - *h;
  716.         break;
  717.     case '+':
  718.         *r = *r + *h;
  719.         break;
  720.     case '*':
  721.         *r = *r * *h;
  722.         break;
  723.     case '/':
  724.         *r = (*r) / (*h);
  725.         break;
  726.     case '%':
  727.         t = (*r) / (*h);
  728.         *r = *r - (t * (*h));
  729.         break;
  730.     case '^':
  731.         ex = *r;
  732.         if (*h == 0) {
  733.             *r = 1;
  734.             break;
  735.         }
  736.         for (t = *h - 1; t > 0; --t)
  737.             *r = (*r) * ex;
  738.         break;
  739.     }
  740.     return;
  741. }
  742.  
  743.  
  744. /*
  745.  * unary - reverse the sign.
  746.  */
  747. void
  748. unary(o, r)
  749. char    o;
  750. int    *r;
  751. {
  752.     if (o == '-')
  753.         *r = -(*r);
  754.     return;
  755. }
  756.  
  757.  
  758. /*
  759.  * getval - find the value of a variable.
  760.  */
  761. int
  762. getval(s)
  763. char    *s;
  764. {
  765.     if (!isalpha(*s)) {
  766.         b_error(4);        /* not a variable */
  767.         return 0;        /* NOTREACHED */
  768.     }
  769.     return variables[toupper(*s)-'A'];
  770. }
  771.  
  772.  
  773.  
  774.  
  775. /*
  776.  * putback - return a token to input stream.
  777.  */
  778. void
  779. putback(ptoken)
  780. char    *ptoken;
  781. {
  782.  
  783.     char    *t;
  784.  
  785.     t = ptoken;
  786.     for (; *t; t++)
  787.         prog--;
  788.     return;
  789. }
  790.  
  791.  
  792. /*
  793.  * b_error - display an error message.
  794.  */
  795. void
  796. b_error(error)
  797. int    error;
  798. {
  799.     static char    *e[] = {
  800.         "syntax error",             /*  0 */
  801.         "unbalanced parentheses",         /*  1 */
  802.         "no expression present",         /*  2 */
  803.         "equals sign expected",         /*  3 */
  804.         "not a variable",             /*  4 */
  805.         "label table full",             /*  5 */
  806.         "duplicate label",             /*  6 */
  807.         "undefined label",             /*  7 */
  808.         "THEN expected",             /*  8 */
  809.         "TO expected",                 /*  9 */
  810.         "too many nested FOR loops",         /* 10 */
  811.         "NEXT without FOR",             /* 11 */
  812.         "too many nested GOSUBs",         /* 12 */
  813.         "RETURN without GOSUB",         /* 13 */
  814.         "invalid row number",             /* 14 */
  815.         "invalid column number",         /* 15 */
  816.         "unbalanced double quotes"        /* 16 */
  817.     };
  818.     fprintf (stderr, "\nBASIC: %s\n", e[error]);
  819.     longjmp(e_buf, 1);    /* return to save point */
  820. }
  821.  
  822.  
  823. /*
  824.  * loop_up - find a token's internal representation in the token table.
  825.  */
  826. int
  827. look_up(s)
  828. char    *s;
  829. {
  830.     register int    i;
  831.     char    *p;
  832.  
  833.     /* convert to lowercase */
  834.     p = s;
  835.     while (*p) {
  836.         *p = tolower(*p);
  837.         p++;
  838.     }
  839.  
  840.     /* see if token is in table */
  841.     for (i = 0; *table[i].command; i++)
  842.         if (strcmp(table[i].command, s) == 0)
  843.             return (table[i].tokenid);    /* valid command */
  844.  
  845.     return(0);                    /* unknown command */
  846. }
  847.  
  848.  
  849. /*
  850.  * isdelim - return true if c is a delimiter.
  851.  */
  852. isdelim(c)
  853. char    c;
  854. {
  855.     if (strchr(" ;,+-<>/*%^=()", c) || c == 9 || c == '\n' || c == 0)
  856.         return 1;
  857.     return 0;
  858. }
  859.  
  860.  
  861. /*
  862.  * iswhite - return 1 if c is space or tab.
  863.  */
  864. iswhite(c)
  865. char    c;
  866. {
  867.     if (c == ' ' || c == '\t')
  868.         return 1;
  869.     else
  870.         return 0;
  871. }
  872.  
  873.  
  874.